package com.xiaoshuidi.cloud.framework.filings.core.service;

import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.xiaoshuidi.cloud.framework.filings.config.FilingsProperties;
import com.xiaoshuidi.cloud.framework.filings.core.FilingsApi;
import com.xiaoshuidi.cloud.framework.filings.core.enums.UriEnum;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.CommonFilingsResponse;
import com.xiaoshuidi.cloud.framework.filings.core.service.dto.FilesUploadBo;
import com.xiaoshuidi.cloud.framework.filings.core.util.RSAUtil;
import com.xiaoshuidi.cloud.framework.filings.core.util.SignUtil;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;

/**
 * @Author Feng
 * @date 2023/5/6
 */
@Slf4j
public class FilingsApiImpl<T, E> implements FilingsApi<T, E> {

    @Resource
    private FilingsProperties properties;

    @Override
    public CommonFilingsResponse<T> execute(E e, UriEnum uri, Class<T> clz) {
        long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        String appKey = RSAUtil.encryptPublicKeyRSA(properties.getApiKey(), properties.getPublicKey());
        String sign = SignUtil.generateSign(e, timestamp, uri.getMethod().equals("GET"), properties.getApiKey());
        String url = properties.getHost() + uri.getUri();
        String response = null;
        if ("GET".equals(uri.getMethod())) {
            response = get(e, timestamp, appKey, sign, url);
        } else if ("POST".equals(uri.getMethod())) {
            response = post(e, timestamp, appKey, sign, url);
        } else if ("POST_MULTIPART".equals(uri.getMethod())) {
            response = post1(e, timestamp, appKey, sign, url);
        }
        log.info("请求备案响应，response: {}", response);
        CommonFilingsResponse<T> commonResponse = JSONObject.parseObject(response, new TypeReference<CommonFilingsResponse<T>>(clz) {
        });
        return commonResponse;
    }

    private String post(E e, long timestamp, String appKey, String sign, String url) {
        String response = HttpRequest.post(url)
                .header("timestamp", String.valueOf(timestamp))
                .header("appKey", appKey)
                .header(Header.CONTENT_TYPE, "application/json")
                .header("sign", sign)
                .body(JSONObject.toJSONString(e))
                .execute().body();
        return response;
    }

    private String post1(E e, long timestamp, String appKey, String sign, String url) {
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(e), new TypeReference<Map<String, Object>>() {
        });
        map.remove("files");
        map.remove("fileName");
        FilesUploadBo bo = (FilesUploadBo) e;
        String response = HttpRequest.post(url)
                .header("timestamp", String.valueOf(timestamp))
                .header("appKey", appKey)
                .header(Header.CONTENT_TYPE, "multipart/form-data")
                .header("sign", sign)
                .form("files", bo.getMultipartFile().getResource(), bo.getFileName())
                .form(map)
                .execute().body();
        return response;
    }

    private String get(E e, long timestamp, String appKey, String sign, String url) {
        Map<String, Object> map = JSON.parseObject(JSON.toJSONString(e), new TypeReference<Map<String, Object>>() {
        });
        String response = HttpRequest.get(url)
                .header("timestamp", String.valueOf(timestamp))
                .header("appKey", appKey)
                .header(Header.CONTENT_TYPE, "application/json")
                .header("sign", sign)
                .form(map)
                .execute().body();

        return response;
    }
}
